/*
 * FlowLayout
 * Copyright (C) 2004-2008 Trolltech ASA. All rights reserved.
 * Modified by Philip Pronin, 2008
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "flowLayout.h"

FlowLayout::FlowLayout(QWidget* parent, int margin, int spacing) : QLayout(parent), cachedWidth(-1) {
	setMargin(margin);
	setSpacing(spacing);
}

FlowLayout::FlowLayout(int spacing) {
	setSpacing(spacing);
}

FlowLayout::~FlowLayout() {
	while (QLayoutItem * item = takeAt(0)) delete item;
}

void FlowLayout::addItem(QLayoutItem* item) {
	cachedWidth = -1;
	itemList.append(item);
}

int FlowLayout::count() const {
	return itemList.size();
}

QLayoutItem* FlowLayout::itemAt(int index) const {
	return itemList.value(index);
}

QLayoutItem* FlowLayout::takeAt(int index) {
	cachedWidth = -1;
	if (index >= 0 && index < itemList.size()) return itemList.takeAt(index);
	return 0;
}

Qt::Orientations FlowLayout::expandingDirections() const {
	return 0;
}

bool FlowLayout::hasHeightForWidth() const {
	return true;
}

int FlowLayout::heightForWidth(int width) const {
	if (cachedWidth != width) {
		FlowLayout* _this = (FlowLayout*)this;
		_this->cachedHeight = doLayout(QRect(0, 0, width, 0), true) + 2 * margin();
	}
	return cachedHeight;
}

void FlowLayout::setGeometry(const QRect &rect) {
	QLayout::setGeometry(rect);
	doLayout(rect, false);
}

QSize FlowLayout::sizeHint() const {
	return minimumSize();
}

QSize FlowLayout::minimumSize() const {
	QSize size;
	foreach (QLayoutItem* item, itemList) size = size.expandedTo(item->minimumSize());
	return size += QSize(2 * margin(), 2 * margin());
}

int FlowLayout::doLayout(const QRect &rect, bool testOnly) const {
	int x = rect.x(), y = rect.y(), lineHeight = 0;

	QLayoutItem* item;
	foreach (item, itemList){
		int nextX = x + item->sizeHint().width() + spacing();
		if (nextX - spacing()> rect.right() && lineHeight> 0) {
			x = rect.x();
			y = y + lineHeight + spacing();
			nextX = x + item->sizeHint().width() + spacing();
			lineHeight = 0;
		}

		if (!testOnly) item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));

		x = nextX;
		lineHeight = qMax(lineHeight, item->sizeHint().height());
	}

	return y + lineHeight - rect.y();
}
